package com.example.service;

import com.example.common.enums.ResultCodeEnum;
import com.example.entity.Account;
import com.example.exception.CustomException;
import com.example.mapper.AdminMapper;
import com.example.mapper.DoctorMapper;
import com.example.mapper.PatientsMapper;
import com.example.mapper.PharmacistMapper;
import com.example.utils.BcryptUtil;
import com.example.utils.JwtUtil;
import com.example.utils.RedisUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Map;

@Service
public class LoginService {
    @Autowired
    private AdminMapper adminMapper;
    @Autowired
    private PatientsMapper patientsMapper;
    @Autowired
    private DoctorMapper doctorMapper;
    @Autowired
    private PharmacistMapper pharmacistMapper;
    @Autowired
    private RedisUtils redisUtils;

    public Account handelLogin(Account account) {
        // 根据角色处理不同角色的登录逻辑
        Account dbUser = switch (account.getRole().toUpperCase()) {
            case "ADMIN" -> adminMapper.selectByUsername(account.getUsername());
            case "DOCTOR" -> doctorMapper.selectByUsername(account.getUsername());
            case "PATIENT" -> patientsMapper.selectByUsername(account.getUsername());
            case "PHARMACIST" -> pharmacistMapper.selectByUsername(account.getUsername());
            default -> throw new CustomException(ResultCodeEnum.INVALID_ROLE);
        };

        // 校验用户是否存在
        if (dbUser == null) {
            throw new CustomException(ResultCodeEnum.USER_NOT_EXIST);
        }


        // 校验密码是否正确
        if (!BcryptUtil.match(account.getPassword(), dbUser.getPassword())) {
            throw new CustomException(ResultCodeEnum.USER_ACCOUNT_ERROR);
        }

        //查看redis中是否有已登录未过期的token
        String redisKey = "TOKEN_" + dbUser.getUsername();
        String token = null;
        if (redisUtils.exists(redisKey)) {
            token = (String) redisUtils.get(redisKey);

            //将取出的token过期时间重置为一小时
            redisUtils.set(redisKey, token, 3600L);

        }else{
            // 生成JWT token
            token = generateJwtToken(dbUser);

            // 将token存入Redis, 设置有效期为1小时
            redisUtils.set(redisKey, token, 3600L); // 3600秒 = 1小时
        }
        // 将生成的token加入到返回的Account对象中
        dbUser.setToken(token);

        return dbUser;
    }

    /**
     * 生成JWT token的辅助方法
     */
    private String generateJwtToken(Account dbUser) {
        // 准备token的claims数据
        Map<String, Object> claims = Map.of(
                "id", dbUser.getId(),
                "username", dbUser.getUsername(),
                "role", dbUser.getRole()
        );

        // 调用JwtUtil生成token
        return JwtUtil.genToken(claims);
    }
}
